home *** CD-ROM | disk | FTP | other *** search
- /* Micro Cornucopia Magazine Issue #45
- Life Figure 1 LIFE.C
-
- Hard coded for CGA */
-
-
- #include <graphics.h>
- #define BYTE unsigned char
- #define WORD unsigned int
- #define FALSE 0
- #define TRUE 1
-
- /* rule parameters governing births and deaths */
- #define EL 2 /*envrnmnt,lower:death if n_cnt<EL*/
- #define EU 3 /*envrnmnt,upper: or n_cnt>EU*/
- #define FL 3 /*fertlty,lower:birth if n_cnt>=FL*/
- #define FU 3 /*fertlty,upper: and n_cnt<=FU*/
- /* configuration constants (array sizes) */
- #define MAX_ALIVE 600 /* max # living cells */
- #define MAX_GHOST 1700/*max # non-live neighbors*/
- #define MAX_BIRTH 300/* max # births/generation */
- #define MAX_DEATH 300/* max # deaths/generation */
- #define MAX_X 200 /* width of grid */
- #define MAX_Y 200 /* height of grid */
- /* global variable declarations */
- BYTE n_cnt[MAX_X][MAX_Y]; /* neighbor count ... */
- /* ... for all cells */
- BYTE alive[2][MAX_ALIVE]; /* list/living cells */
- BYTE ghost[2][MAX_GHOST]; /*list/neighbor cells*/
- BYTE birth[2][MAX_BIRTH]; /* list/new births */
- BYTE death[2][MAX_DEATH]; /* list/new deaths */
- WORD alive_cnt; /* size of list of living cells */
- WORD ghost_cnt; /* size of list of neighbors */
- WORD birth_cnt; /* size of list of births */
- WORD death_cnt; /* size of list of deaths */
-
- void locate_deaths(void)
- {
- BYTE c, x, y;
- WORD index;
-
- death_cnt = index = 0;
- while (index < alive_cnt)
- {
- x = alive[0][index]; y = alive[1][index];
- c = n_cnt[x][y] - 1;
- if (c >= EL && c <= EU) index++;
- else
- {
- death[0][death_cnt] = x;
- death[1][death_cnt] = y;
- death_cnt++;
- alive_cnt--;
- alive[0][index] = alive[0][alive_cnt];
- alive[1][index] = alive[1][alive_cnt];
- }
- }
- }
-
- void locate_births(void)
- {
- BYTE c, x, y;
- WORD index;
- birth_cnt = index = 0;
- while (index < ghost_cnt)
- {
- x = ghost[0][index]; y = ghost[1][index];
- c = n_cnt[x][y];
- if (c >= FL && c <= FU)
- {
- if (x > 0 && y > 0 && x < MAX_X-1 &&
- y < MAX_Y-1)
- {
- birth[0][birth_cnt] = x;
- birth[1][birth_cnt] = y;
- birth_cnt++;
- }
- ghost_cnt--;
- ghost[0][index] = ghost[0][ghost_cnt];
- ghost[1][index] = ghost[1][ghost_cnt];
- }
- else if (c == 0)
- {
- ghost_cnt--;
- ghost[0][index] = ghost[0][ghost_cnt];
- ghost[1][index] = ghost[1][ghost_cnt];
- }
- else index++;
- }
- }
-
- void process_births(void)
- {
- BYTE x, y;
- WORD index;
-
- for (index = 0; index < birth_cnt; index++)
- {
- x = alive[0][alive_cnt] = birth[0][index];
- y = alive[1][alive_cnt] = birth[1][index];
- alive_cnt++;
- n_cnt[x][y]++;
- x++;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- y++;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- x--;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- x--;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- y--;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- y--;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- x++;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- x++;
- if (n_cnt[x][y]++ == 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- }
- }
-
-
- void process_deaths(void)
- {
- BYTE i, j, x, y;
- WORD index;
-
- for (index = 0; index < death_cnt; index++)
- {
- x = death[0][index];
- y = death[1][index];
- for (i = x - 1; i < x + 2; i++)
- for (j = y - 1; j < y + 2; j++)
- n_cnt[i][j]--;
- }
- for (index = 0; index < death_cnt; index++)
- {
- x = death[0][index];
- y = death[1][index];
- if (n_cnt[x][y] != 0)
- {
- ghost[0][ghost_cnt] = x;
- ghost[1][ghost_cnt] = y;
- ghost_cnt++;
- }
- }
- }
-
- void screen_update(void)
- {
- BYTE x, y;
- WORD index;
-
- for (index = 0; index < birth_cnt; index++)
- {
- x = birth[0][index]; y = birth[1][index];
- putpixel(x, y, 1);
- }
- for (index = 0; index < death_cnt; index++)
- {
- x = death[0][index]; y = death[1][index];
- putpixel(x, y, 2);
- }
- }
-
- void init_grid(void)
- {
- BYTE x, y;
- WORD index;
-
- for (x = 0; x < MAX_X; x++)
- for (y = 0; y < MAX_Y; y++)
- n_cnt[x][y] = 0;
- birth[0][0] = 100; birth[1][0] = 100;
- birth[0][1] = 101; birth[1][1] = 100;
- birth[0][2] = 102; birth[1][2] = 100;
- birth[0][3] = 102; birth[1][3] = 99;
- birth[0][4] = 101; birth[1][4] = 101;
- birth_cnt = 5; alive_cnt = 0;
- ghost_cnt = 0;
- screen_update();
- for (index = 0; index < birth_cnt; index++)
- {
- x = birth[0][index]; y = birth[1][index];
- n_cnt[x][y]++;
- }
- process_births();
- for (index = 0; index < birth_cnt; index++)
- {
- x = birth[0][index]; y = birth[1][index];
- n_cnt[x][y]--;
- }
- }
-
- void main(void)
- {
- int step = FALSE; int done = FALSE;
- int generation = 0;
- int gd = CGA; int gm = CGAC0;
- initgraph(&gd, &gm, "");
- printf("Generation: 0 Run Pause Step Quit");
- init_grid();
- gotoxy(1, 1); getch();
- while (!done)
- {
- gotoxy(13, 1); printf("%d", ++generation);
- locate_deaths(); locate_births();
- process_births(); process_deaths();
- screen_update();
- if (kbhit() || step)
- {
- switch(toupper(getch()))
- {
- case 'Q': done = TRUE;
- break;
- case 'P': getch();
- break;
- case 'S': step = 1;
- break;
- case 'R': step = 0;
- break;
- }
- }
- }
- closegraph();
- }
-
-
-